/**
 * $version:  0.1 
 * $Date: 2011-01-21 
 *
 * Copyright (C) 2010-2011 Jawa Software. All rights reserved.
 *
 */

package org.jawa.user;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.jawa.database.SequenceManager;
import org.jawa.util.ClassUtils;
import org.jawa.util.JawaConstants;
import org.jawa.util.JawaGlobals;
import org.jawa.util.cache.Cache;
import org.jawa.util.cache.CacheFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 用户管理，包括加载、查询、创建、删除以及修改.
 * 
 * @see User
 */
public class UserManager {

	private static final Logger Log = LoggerFactory
			.getLogger(UserManager.class);

	// 单一实例.
	private static class UserManagerContainer {
		private static UserManager instance = new UserManager();
	}

	/**
	 * 返回当前用户操作提供类.
	 * 
	 * @return 用户操作提供类.
	 */
	public static UserProvider getUserProvider() {
		return UserManagerContainer.instance.provider;
	}

	/**
	 * 返回 UserManager 的单一实例.
	 * 
	 * @return UserManager 实例.
	 */
	public static UserManager getInstance() {
		return UserManagerContainer.instance;
	}

	/** 当前用户的缓存. */
	private Cache<Long, User> userCache;

	private UserProvider provider;

	private UserManager() {
		// 初始化缓存.
		userCache = CacheFactory.createCache("user");

		// 初始化用户操作提供类.
		initProvider();

		// 注册事件.
		UserEventListener userListener = new UserEventListener() {
			public void userCreated(User user, Map<String, Object> params) {
				userCache.put(user.getId(), user);
			}

			public void userDeleting(User user, Map<String, Object> params) {
				userCache.remove(user.getId());
			}

			public void userModified(User user, Map<String, Object> params) {
				userCache.put(user.getId(), user);
			}
		};
		UserEventDispatcher.addListener(userListener);
	}

	/**
	 * 创建用户.
	 * 
	 * @param user
	 *            要创建的用户.
	 * @return a new User.
	 * @throws UserAlreadyExistsException
	 *             username 已经存在.
	 * @throws UnsupportedOperationException
	 *             用户操作提供类不支持的方法
	 */
	public User createUser(User user) throws UserAlreadyExistsException {

		if (null == user) {
			throw new NullPointerException("用户不可以为空！");
		}
		
		if (null == user.getId()) {
			throw new IllegalArgumentException("用户  id 不可以为空！");
		}

		if (StringUtils.isEmpty(user.getUsername())) {
			throw new IllegalArgumentException("用户  username 不可以为空！");
		}

		user = provider.createUser(user);

		// 激活事件.
		Map<String, Object> params = Collections.emptyMap();
		UserEventDispatcher.dispatchEvent(user,
				UserEventDispatcher.EventType.user_created, params);
		return user;
	}

	/**
	 * 删除用户.
	 * 
	 * @param user
	 *            要删除的用户.
	 */
	public void deleteUser(User user) {
		// 激活事件.
		Map<String, Object> params = Collections.emptyMap();
		UserEventDispatcher.dispatchEvent(user,
				UserEventDispatcher.EventType.user_deleting, params);

		provider.deleteUser(user.getId());
	}

	/**
	 * 返回指定 username 的用户.
	 * 
	 * @param username
	 *            用户的 username.
	 * @return username 等于 <tt>username</tt> 的用户.
	 * @throws UserNotFoundException
	 *             用户没有找到.
	 */
	public User getUserByUsername(String username) throws UserNotFoundException {
		if (username == null) {
			throw new UserNotFoundException("Username 不可以为空!");
		}
		return provider.loadUserByUsername(username);
	}

	/**
	 * 返回指定 userId 的用户.
	 * 
	 * @param userId
	 *            用户的 userId .
	 * @return userId 等于 <tt>userId</tt> 的用户.
	 * @throws UserNotFoundException
	 *             用户没有找到.
	 */
	public User getUser(Long userId) throws UserNotFoundException {
		if (userId == null) {
			throw new UserNotFoundException("UserId cannot be null");
		}

		User user = userCache.get(userId);
		if (user == null) {
			synchronized (userId) {
				user = userCache.get(userId);
				if (user == null) {
					user = provider.loadUserByUserid(userId);
					userCache.put(user.getId(), user);
				}
			}
		}
		return user;
	}

	/**
	 * 返回系统中的总用户数.
	 * 
	 * @return 系统中的总用户数.
	 */
	public int getUserCount() {
		return provider.getUserCount();
	}

	/**
	 * 返回系统中所有的用户，不可以修改的.
	 * 
	 * @return 不可以修改的用户集合.
	 */
	public Collection<User> getUsers() {
		return provider.getUsers();
	}

	/**
	 * 返回系统中所有的用户的 userId 集合，不可以修改的.
	 * 
	 * @return 不可以修改的用户userId 的集合.
	 */
	public Collection<Long> getUserIds() {
		return provider.getUserIds();
	}

	/**
	 * 返回索引范围内的用户集合。
	 * 
	 * @param startIndex
	 *            起始索引.
	 * @param numResults
	 *            要显示的用户数据数量.
	 * @return 用户集合.
	 */
	public Collection<User> getUsers(int startIndex, int numResults) {
		return provider.getUsers(startIndex, numResults);
	}

	/**
	 * 根据查询条件，返回用户集合。
	 * 
	 * @param fields
	 *            查询字段.
	 * @param query
	 *            查询字段条件值.
	 * @return 用户集合.
	 */
	public Collection<User> findUsers(List<String> fields, List<String> query) {
		return provider.findUsers(fields, query);
	}

	/**
	 * 根据查询条件，返回索引范围内的用户集合。
	 * 
	 * @param fields
	 *            查询字段.
	 * @param query
	 *            查询字段条件值.
	 * @param startIndex
	 *            起始索引.
	 * @param numResults
	 *            要显示的用户数据数量.
	 * @return 用户集合.
	 */
	public Collection<User> findUsers(List<String> fields, List<String> query,
			int startIndex, int numResults) {
		return provider.findUsers(fields, query, startIndex, numResults);
	}

	private void initProvider() {
		JawaGlobals.getProperty("provider.user.className");

		String className = JawaGlobals.getProperty("provider.user.className",
				"org.jawa.user.DefaultUserProvider");
		if (provider == null
				|| !className.equals(provider.getClass().getName())) {
			try {
				Class c = ClassUtils.forName(className);
				provider = (UserProvider) c.newInstance();
			} catch (Exception e) {
				Log.error("不能加载用户操作的提供类: " + className, e);
				provider = new DefaultUserProvider();
			}
		}
	}
}